const logger = require('./logger');
const User = require('../models/User');
const Order = require('../models/Order');

/**
 * 通知服务类
 * 处理各种通知功能，包括实时通知、邮件通知、短信通知等
 */
class NotificationService {
  constructor(socketService) {
    this.socketService = socketService;
  }

  /**
   * 发送订单状态更新通知
   * @param {string} orderId - 订单ID
   * @param {string} newStatus - 新状态
   * @param {string} message - 通知消息
   */
  async sendOrderStatusNotification(orderId, newStatus, message) {
    try {
      const order = await Order.findById(orderId)
        .populate('user', 'name email phone')
        .populate('caregiver', 'name email phone');

      if (!order) {
        throw new Error('订单不存在');
      }

      const notificationData = {
        type: 'order_status_update',
        orderId,
        status: newStatus,
        message,
        timestamp: new Date()
      };

      // 发送实时通知给用户
      if (order.user) {
        await this.sendRealTimeNotification(order.user._id, 'order-notification', {
          ...notificationData,
          title: '订单状态更新',
          content: `您的订单状态已更新为：${this.getStatusText(newStatus)}`
        });
      }

      // 发送实时通知给护理员
      if (order.caregiver) {
        await this.sendRealTimeNotification(order.caregiver._id, 'order-notification', {
          ...notificationData,
          title: '订单状态更新',
          content: `订单状态已更新为：${this.getStatusText(newStatus)}`
        });
      }

      // 发送到订单房间
      if (this.socketService) {
        this.socketService.sendToOrder(orderId, 'order-status-notification', notificationData);
      }

      logger.info(`订单状态通知已发送: ${orderId} -> ${newStatus}`);
    } catch (error) {
      logger.error('发送订单状态通知失败:', error);
    }
  }

  /**
   * 发送新订单通知给护理员
   * @param {string} orderId - 订单ID
   * @param {string} caregiverId - 护理员ID
   */
  async sendNewOrderNotification(orderId, caregiverId) {
    try {
      const order = await Order.findById(orderId)
        .populate('user', 'name avatar')
        .populate('service', 'name');

      if (!order) {
        throw new Error('订单不存在');
      }

      const notificationData = {
        type: 'new_order',
        orderId,
        title: '新订单通知',
        content: `您收到来自 ${order.user.name} 的新订单：${order.service.name}`,
        orderInfo: {
          id: orderId,
          serviceName: order.service.name,
          customerName: order.user.name,
          customerAvatar: order.user.avatar,
          startTime: order.startDateTime,
          amount: order.totalAmount
        },
        timestamp: new Date()
      };

      // 发送实时通知
      await this.sendRealTimeNotification(caregiverId, 'new-order-notification', notificationData);

      // 这里可以添加推送通知、短信通知等
      // await this.sendPushNotification(caregiverId, notificationData);
      // await this.sendSMSNotification(caregiverId, notificationData);

      logger.info(`新订单通知已发送给护理员: ${caregiverId}`);
    } catch (error) {
      logger.error('发送新订单通知失败:', error);
    }
  }

  /**
   * 发送支付成功通知
   * @param {string} orderId - 订单ID
   */
  async sendPaymentSuccessNotification(orderId) {
    try {
      const order = await Order.findById(orderId)
        .populate('user', 'name email phone')
        .populate('caregiver', 'name email phone')
        .populate('service', 'name');

      if (!order) {
        throw new Error('订单不存在');
      }

      const notificationData = {
        type: 'payment_success',
        orderId,
        title: '支付成功',
        content: `订单支付成功，金额：¥${order.totalAmount}`,
        orderInfo: {
          id: orderId,
          serviceName: order.service.name,
          amount: order.totalAmount,
          paymentMethod: order.paymentMethod
        },
        timestamp: new Date()
      };

      // 通知用户
      if (order.user) {
        await this.sendRealTimeNotification(order.user._id, 'payment-notification', {
          ...notificationData,
          content: `您的订单支付成功，金额：¥${order.totalAmount}`
        });
      }

      // 通知护理员
      if (order.caregiver) {
        await this.sendRealTimeNotification(order.caregiver._id, 'payment-notification', {
          ...notificationData,
          content: `订单支付成功，您将获得收入：¥${(order.totalAmount * 0.8).toFixed(2)}`
        });
      }

      logger.info(`支付成功通知已发送: ${orderId}`);
    } catch (error) {
      logger.error('发送支付成功通知失败:', error);
    }
  }

  /**
   * 发送服务开始通知
   * @param {string} orderId - 订单ID
   */
  async sendServiceStartNotification(orderId) {
    try {
      const order = await Order.findById(orderId)
        .populate('user', 'name')
        .populate('caregiver', 'name')
        .populate('service', 'name');

      if (!order) {
        throw new Error('订单不存在');
      }

      const notificationData = {
        type: 'service_start',
        orderId,
        title: '服务开始',
        content: `护理员 ${order.caregiver.name} 已开始为您提供 ${order.service.name} 服务`,
        timestamp: new Date()
      };

      // 通知用户
      if (order.user) {
        await this.sendRealTimeNotification(order.user._id, 'service-notification', notificationData);
      }

      logger.info(`服务开始通知已发送: ${orderId}`);
    } catch (error) {
      logger.error('发送服务开始通知失败:', error);
    }
  }

  /**
   * 发送服务完成通知
   * @param {string} orderId - 订单ID
   */
  async sendServiceCompleteNotification(orderId) {
    try {
      const order = await Order.findById(orderId)
        .populate('user', 'name')
        .populate('caregiver', 'name')
        .populate('service', 'name');

      if (!order) {
        throw new Error('订单不存在');
      }

      const notificationData = {
        type: 'service_complete',
        orderId,
        title: '服务完成',
        content: `护理员 ${order.caregiver.name} 已完成 ${order.service.name} 服务，请您确认并评价`,
        timestamp: new Date()
      };

      // 通知用户
      if (order.user) {
        await this.sendRealTimeNotification(order.user._id, 'service-notification', notificationData);
      }

      logger.info(`服务完成通知已发送: ${orderId}`);
    } catch (error) {
      logger.error('发送服务完成通知失败:', error);
    }
  }

  /**
   * 发送护理员位置更新通知
   * @param {string} orderId - 订单ID
   * @param {Object} location - 位置信息
   */
  async sendLocationUpdateNotification(orderId, location) {
    try {
      const order = await Order.findById(orderId)
        .populate('user', 'name')
        .populate('caregiver', 'name');

      if (!order) {
        throw new Error('订单不存在');
      }

      const notificationData = {
        type: 'location_update',
        orderId,
        caregiverId: order.caregiver._id,
        caregiverName: order.caregiver.name,
        location,
        timestamp: new Date()
      };

      // 通知用户护理员位置更新
      if (order.user) {
        await this.sendRealTimeNotification(order.user._id, 'location-update', notificationData);
      }

      // 发送到订单房间
      if (this.socketService) {
        this.socketService.sendToOrder(orderId, 'caregiver-location-update', notificationData);
      }

      logger.info(`位置更新通知已发送: ${orderId}`);
    } catch (error) {
      logger.error('发送位置更新通知失败:', error);
    }
  }

  /**
   * 发送系统通知
   * @param {string} userId - 用户ID
   * @param {string} title - 通知标题
   * @param {string} content - 通知内容
   * @param {Object} data - 额外数据
   */
  async sendSystemNotification(userId, title, content, data = {}) {
    try {
      const notificationData = {
        type: 'system',
        title,
        content,
        data,
        timestamp: new Date()
      };

      await this.sendRealTimeNotification(userId, 'system-notification', notificationData);
      
      logger.info(`系统通知已发送给用户: ${userId}`);
    } catch (error) {
      logger.error('发送系统通知失败:', error);
    }
  }

  /**
   * 发送实时通知
   * @param {string} userId - 用户ID
   * @param {string} event - 事件名称
   * @param {Object} data - 通知数据
   */
  async sendRealTimeNotification(userId, event, data) {
    try {
      if (this.socketService) {
        const sent = this.socketService.sendToUser(userId, event, data);
        if (!sent) {
          // 用户不在线，可以保存通知到数据库，等用户上线时发送
          await this.saveOfflineNotification(userId, event, data);
        }
      }
    } catch (error) {
      logger.error('发送实时通知失败:', error);
    }
  }

  /**
   * 保存离线通知
   * @param {string} userId - 用户ID
   * @param {string} event - 事件名称
   * @param {Object} data - 通知数据
   */
  async saveOfflineNotification(userId, event, data) {
    try {
      // 这里可以实现将通知保存到数据库的逻辑
      // 例如创建一个 Notification 模型来存储离线通知
      logger.info(`保存离线通知: 用户 ${userId}, 事件 ${event}`);
    } catch (error) {
      logger.error('保存离线通知失败:', error);
    }
  }

  /**
   * 发送推送通知（移动端）
   * @param {string} userId - 用户ID
   * @param {Object} notificationData - 通知数据
   */
  async sendPushNotification(userId, notificationData) {
    try {
      // 这里可以集成第三方推送服务，如极光推送、友盟推送等
      // const user = await User.findById(userId);
      // if (user.pushToken) {
      //   await pushService.send(user.pushToken, notificationData);
      // }
      
      logger.info(`推送通知: 用户 ${userId}`);
    } catch (error) {
      logger.error('发送推送通知失败:', error);
    }
  }

  /**
   * 发送短信通知
   * @param {string} userId - 用户ID
   * @param {Object} notificationData - 通知数据
   */
  async sendSMSNotification(userId, notificationData) {
    try {
      // 这里可以集成短信服务，如阿里云短信、腾讯云短信等
      // const user = await User.findById(userId);
      // if (user.phone) {
      //   await smsService.send(user.phone, notificationData.content);
      // }
      
      logger.info(`短信通知: 用户 ${userId}`);
    } catch (error) {
      logger.error('发送短信通知失败:', error);
    }
  }

  /**
   * 发送邮件通知
   * @param {string} userId - 用户ID
   * @param {Object} notificationData - 通知数据
   */
  async sendEmailNotification(userId, notificationData) {
    try {
      // 这里可以集成邮件服务，如SendGrid、阿里云邮件推送等
      // const user = await User.findById(userId);
      // if (user.email) {
      //   await emailService.send(user.email, notificationData);
      // }
      
      logger.info(`邮件通知: 用户 ${userId}`);
    } catch (error) {
      logger.error('发送邮件通知失败:', error);
    }
  }

  /**
   * 获取状态文本
   * @param {string} status - 状态代码
   * @returns {string} 状态文本
   */
  getStatusText(status) {
    const statusMap = {
      'pending': '待确认',
      'confirmed': '已确认',
      'in_progress': '进行中',
      'completed': '已完成',
      'cancelled': '已取消',
      'refunded': '已退款'
    };
    return statusMap[status] || status;
  }

  /**
   * 批量发送通知
   * @param {Array} userIds - 用户ID数组
   * @param {string} event - 事件名称
   * @param {Object} data - 通知数据
   */
  async sendBulkNotification(userIds, event, data) {
    try {
      const promises = userIds.map(userId => 
        this.sendRealTimeNotification(userId, event, data)
      );
      await Promise.all(promises);
      
      logger.info(`批量通知已发送给 ${userIds.length} 个用户`);
    } catch (error) {
      logger.error('发送批量通知失败:', error);
    }
  }

  /**
   * 发送广播通知
   * @param {string} event - 事件名称
   * @param {Object} data - 通知数据
   * @param {string} room - 房间名称（可选）
   */
  async sendBroadcastNotification(event, data, room = null) {
    try {
      if (this.socketService && this.socketService.io) {
        if (room) {
          this.socketService.io.to(room).emit(event, data);
        } else {
          this.socketService.io.emit(event, data);
        }
      }
      
      logger.info(`广播通知已发送: ${event}`);
    } catch (error) {
      logger.error('发送广播通知失败:', error);
    }
  }
}

module.exports = NotificationService;